﻿using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using ZoneLineNew.Core.Extensions;
using ZoneLineNew.Core.Utils;
using ZoneLineNew.Enums;
using ZoneLineNew.Models.Dto;
using ZoneLineNew.Models.Entity.BaseInfo;
using ZoneLineNew.Models.Entity.Template;
using ZoneLineNew.Services.DB;
using ZoneLineNew.Services.Message;
using ZoneLineNew.Services.Print;
using ZoneLineNew.ViewModelBase;
using ZoneLineNew.Views.Dialogs;

namespace ZoneLineNew.ViewModels {
    internal class LabelSettingViewModel : NavigationViewModel {

        private readonly PrinterLabelService _printerService;

        public LabelSettingViewModel(
            IRegionManager regionManager,
            IDialogService dialog,
            IMessageService messageBox,
            IEventAggregator eventAggregator,
            IDbOperate<IFreeSqlMainContext> mainDbOperate,
            PrinterLabelService printerService
            ) : base(regionManager, dialog, messageBox, eventAggregator, mainDbOperate) {

            _printerService = printerService;

            var plist = EnumExtensions.ConvertToComboxItems<eParamType>().ToList().Where(o => o.Key != eParamType.Input.ToString());
            ParamTypes.AddRange(plist);

            var vlist = EnumExtensions.ConvertToComboxItems<eValueType>();
            ValueTypes.AddRange(vlist);
        }

        #region Props
        private string _searchTempText;

        public string SearchTempText {
            get { return _searchTempText; }
            set { _searchTempText = value; base.RaisePropertyChanged(); }
        }

        private string _searchParamsText;

        public string SearchParamsText {
            get { return _searchParamsText; }
            set { _searchParamsText = value; base.RaisePropertyChanged(); }
        }

        private bool _isOpen;

        public bool IsOpen {
            get { return _isOpen; }
            set { _isOpen = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<TemplateEntity> _templates = new ObservableCollection<TemplateEntity>();

        public ObservableCollection<TemplateEntity> Templates {
            get { return _templates; }
            set { _templates = value; base.RaisePropertyChanged(); }
        }

        private TemplateEntity _selectedTemplateEntity;

        public TemplateEntity SelectTemplateEntity {
            get { return _selectedTemplateEntity; }
            set { _selectedTemplateEntity = value; base.RaisePropertyChanged(); }
        }


        private ObservableCollection<ParamsDto> _paramss = new ObservableCollection<ParamsDto>();

        public ObservableCollection<ParamsDto> Paramss {
            get { return _paramss; }
            set { _paramss = value; base.RaisePropertyChanged(); }
        }

        private bool _isPrintEnabled = true;

        public bool IsPrintEnabled {
            get { return _isPrintEnabled; }
            set { _isPrintEnabled = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<string> _printNames = new ObservableCollection<string>();

        public ObservableCollection<string> PrintNames {
            get { return _printNames; }
            set { _printNames = value; base.RaisePropertyChanged(); }
        }

        private string _selectPrinterName;

        public string SelectPrinterName {
            get { return _selectPrinterName; }
            set { _selectPrinterName = value; base.RaisePropertyChanged(); }
        }

        #endregion

        #region Commands

        public DelegateCommand SearchTempCommand => new DelegateCommand(() => {
            LoadTempData();
        });

        public DelegateCommand SearchParamsCommand => new DelegateCommand(() => {
            LoadParamsData();
        });

        public DelegateCommand AddTempCommand => new DelegateCommand(() => {
            DialogParameters keyValuePairs = new DialogParameters();
            keyValuePairs.Add("TemplateType", eTemplateType.LabelCode);
            keyValuePairs.Add("Title", "新增标签模板");
            _dialog.ShowDialog(nameof(EditTemplateDialogView), keyValuePairs, (rhs) => {
                if (rhs.Result == ButtonResult.OK) {
                    LoadTempData();
                }
            });
        });

        public DelegateCommand EditTempCommand => new DelegateCommand(() => {
            if (SelectTemplateEntity != null) {
                DialogParameters keyValuePairs = new DialogParameters();
                keyValuePairs.Add("Title", "编辑标签模板");
                keyValuePairs.Add("TemplateType", eTemplateType.LabelCode);
                keyValuePairs.Add("TemplateEntity", JsonConvert.SerializeObject(SelectTemplateEntity));
                _dialog.ShowDialog(nameof(EditTemplateDialogView), keyValuePairs, (rhs) => {
                    if (rhs.Result == ButtonResult.OK) {
                        LoadTempData();
                    }
                });
            }
        });

        public DelegateCommand<TemplateDto> TempSelectionChangedCommand => new DelegateCommand<TemplateDto>((rhs) => {
            if (rhs != null) {
                LoadParamsData();
            }
        }); 

        public DelegateCommand<TemplateDto> CopyTempItemCommand => new DelegateCommand<TemplateDto>((rhs) => {
            if (rhs != null) {
                var ask = _message.Ask("确认是否复制此模板，以及该模板下的所有设置参数的数据？");
                if (ask == System.Windows.MessageBoxResult.OK) {
                    TemplateEntity templateEntity = new TemplateEntity()
                    {
                        ProductID = rhs.ProductID,
                        TemplateType = rhs.TemplateType,
                        TemplateName = rhs.TemplateName + $"Copy_{DateTime.Now.ToString("HHmmss")}",
                        TemplatePath = rhs.TemplatePath,
                    };
                    var newTempId = _mainDbOperate.GetFreeSql().Insert(templateEntity).ExecuteIdentity();
                    var list = _mainDbOperate.GetModelList<ParamsEntity>(o => o.TemplateID == rhs.Id).ToList();
                    foreach (var item in list) {
                        item.Id = default;
                        item.TemplateID = newTempId;
                    }
                    var affRows = _mainDbOperate.GetFreeSql().Insert(list).ExecuteAffrows();
                    if (affRows > 0) {
                        _message.Success("复制成功！");
                    } else {
                        _message.Success("复制失败！");
                        _mainDbOperate.DeleteModel<TemplateEntity>(o => o.Id == newTempId);
                        _mainDbOperate.DeleteModel<ParamsEntity>(o => o.TemplateID == newTempId);
                    }
                    LoadTempData();
                }
            }
        });

        public DelegateCommand<TemplateDto> DeleteTempItemCommand => new DelegateCommand<TemplateDto>((rhs) => {
            if (rhs != null) {
                var ask = _message.Ask($"确认是否删除此【{rhs.TemplateName}】模板，以及该模板下的所有设置参数的数据？");
                if (ask == System.Windows.MessageBoxResult.OK) {
                    _mainDbOperate.DeleteModel<TemplateEntity>(o => o.Id == rhs.Id);
                    _mainDbOperate.DeleteModel<ParamsEntity>(o => o.TemplateID == rhs.Id);
                    LoadTempData();
                }
            }
        });

        public DelegateCommand AddParamsCommand => new DelegateCommand(() => {
            if (SelectTemplateEntity == null) {
                _message.Error("请选择一项左侧模板后再添加！");
                return;
            }
            ParamsEntity = new ParamsEntity();
            ParamsEntity.Sort = Paramss.Count > 0 ? (Paramss.Max(o => o.Sort) + 1) : 1;
            HideViewTable = HideIsAccumulatedByDay = Visibility.Collapsed;
            IsOpen = !IsOpen;
        });

        public DelegateCommand PrintViewCommand => new DelegateCommand(() =>
        {

            if (string.IsNullOrEmpty(SelectPrinterName))
            {
                _message.Warning("请先选择打印机！");
                return;
            }
            try
            {
                if (SelectTemplateEntity != null)
                {
                    IsPrintEnabled = false;

                    // 获取打印参数
                    Dictionary<string, string> printParams;
                    string curIndex;
                    var stationCode = SelectPrinterName == "OP601Printer" ? Enums.ePrintStartionCode.Q_OP580_1
                        : SelectPrinterName == "OP602Printer" ? Enums.ePrintStartionCode.Q_OP580_2
                        : SelectPrinterName == "OP20Printer" ? Enums.ePrintStartionCode.H_OP640 
                        : ePrintStartionCode.None;
                    string qrCode = _printerService.GetPrintParams(SelectTemplateEntity, stationCode, out curIndex, out printParams, false);
                    
                    // 打印预览
                    _printerService.PrintLabelPreview(SelectTemplateEntity.TemplatePath, SelectPrinterName, qrCode, printParams, "预览打印");

                    IsPrintEnabled = true;
                }
            }
            catch (Exception ex)
            {
                _message.GrowError(ex.Message);
                IsPrintEnabled = true;
            }
        });

        public DelegateCommand PrintTestCommand => new DelegateCommand(() => {

            if (string.IsNullOrEmpty(SelectPrinterName)) {
                _message.Warning("请先选择打印机！");
                return;
            }

            try {
                if (SelectTemplateEntity != null) {

                    IsPrintEnabled = false;

                    // 获取打印参数
                    Dictionary<string, string> printParams;
                    string curIndex;
                    var stationCode = SelectPrinterName == "OP601Printer" ? Enums.ePrintStartionCode.Q_OP580_1
                        : SelectPrinterName == "OP602Printer" ? Enums.ePrintStartionCode.Q_OP580_2
                        : SelectPrinterName == "OP20Printer" ? Enums.ePrintStartionCode.H_OP640 
                        : ePrintStartionCode.None;
                    string qrCode = _printerService.GetPrintParams(SelectTemplateEntity, stationCode, out curIndex, out printParams, true);

                    _printerService.PrintLabel(
                        SelectTemplateEntity.TemplatePath,
                        SelectPrinterName,
                        qrCode,
                        printParams, "测试打印");

                    IsPrintEnabled = true;
                }
            } catch (Exception ex) {
                _message.GrowError(ex.Message);
                IsPrintEnabled = true;
            }  
            
        });

        public DelegateCommand BatchPrintCommand => new DelegateCommand(() => {

            if (string.IsNullOrEmpty(SelectPrinterName)) {
                _message.Warning("请先选择打印机！");
                return;
            }

            try {

                if (SelectTemplateEntity != null) {
                    
                    IsPrintEnabled = false;
                    
                    DialogParameters keyValuePairs = new DialogParameters();
                    keyValuePairs.Add("Title", "打印数量编辑");
                    _dialog.ShowDialog(nameof(BatchPrintDialogView), keyValuePairs, (rhs) => {
                        if (rhs.Result == ButtonResult.OK) {
                            var printCount = rhs.Parameters.GetValue<int>("PrintCount");
                            if (printCount > 0) {
                                for (int i = 0; i < printCount; i++) {
                                    // 获取打印参数
                                    Dictionary<string, string> printParams;
                                    string curIndex;
                                    var stationCode = SelectPrinterName == "OP601Printer" ? Enums.ePrintStartionCode.Q_OP580_1
                                        : SelectPrinterName == "OP602Printer" ? Enums.ePrintStartionCode.Q_OP580_2
                                        : SelectPrinterName == "OP20Printer" ? Enums.ePrintStartionCode.H_OP640 
                                        : ePrintStartionCode.None;
                                    string qrCode = _printerService.GetPrintParams(SelectTemplateEntity, stationCode, out curIndex, out printParams, true);

                                    _printerService.PrintLabel(
                                        SelectTemplateEntity.TemplatePath,
                                        SelectPrinterName,
                                        qrCode,
                                        printParams, $"批量打印{i}");
                                }
                            }
                        }
                    });

                    IsPrintEnabled = true;
                }

            } catch (Exception ex) {
                _message.GrowError(ex.Message);
                IsPrintEnabled = true;
            }

        });

        
        public DelegateCommand OpenTempFileCommand => new DelegateCommand(() => {
            try {
                if (!File.Exists(SelectTemplateEntity.TemplatePath)) {
                    _message.Error("模板文件不存在！");
                    return;
                }
                // 启动进程，用默认程序打开文件
                Process.Start(new ProcessStartInfo(SelectTemplateEntity.TemplatePath) {
                    UseShellExecute = true // 关键：启用系统外壳执行（需设置为true）
                });
            } catch (Exception ex) {

                _message.Error(ex.Message);
            }
        });


        public DelegateCommand<ParamsDto> EditParamsCommand => new DelegateCommand<ParamsDto>((rhs) => {
            if (rhs != null) {
                var model = _mainDbOperate.GetModel<ParamsEntity>(o => o.Id == rhs.Id);
                if (model.ParamsType == eParamType.Dynamic) {
                    var vlist = EnumExtensions.ConvertToComboxItems<eValueType>().Where(o => (eValueType)o.Content != eValueType.String);
                    ValueTypes.Clear();
                    ValueTypes.AddRange(vlist);
                    HideViewTable = Visibility.Visible;
                } else {
                    var vlist = EnumExtensions.ConvertToComboxItems<eValueType>().Where(o => (eValueType)o.Content == eValueType.String);
                    ValueTypes.Clear();
                    ValueTypes.AddRange(vlist);
                    HideViewTable = Visibility.Collapsed;
                }

                if (model.ValueType == eValueType.Day) {
                    HideIsAccumulatedByDay = Visibility.Visible;
                } else {
                    HideIsAccumulatedByDay = Visibility.Collapsed;
                }
                ParamsEntity = model;
                IsOpen = true;
            }
        });

        public DelegateCommand<ParamsEntity> DeleteParamsCommand => new DelegateCommand<ParamsEntity>((rhs) => {
            if (rhs != null) {
                var ask = _message.Ask("确认是否删除该数据？");
                if (ask == System.Windows.MessageBoxResult.OK) {
                    _mainDbOperate.DeleteModel<ParamsEntity>(o => o.Id == rhs.Id);
                    LoadParamsData();
                }
            }
        });
        #endregion

        protected override void OnViewLoaded() {

            LoadTempData();
            LoadParamsData();

            var vlist = _mainDbOperate.GetModelList<ViewTableEntity>(o => true);
            ViewTables.Clear();
            ViewTables.AddRange(vlist);

            var plist = PrinterUtil.GetAllPrinterNames();
            PrintNames.Clear();
            PrintNames.AddRange(plist);
            //base.OnViewLoaded();
        }


        private void LoadTempData() {
            var list = _mainDbOperate.GetFreeSql().Select<TemplateEntity, ProductEntity>()
               .LeftJoin((a, b) => a.ProductID == b.Id)
               .Where((a, b) => a.TemplateType == eTemplateType.LabelCode)
               .WhereIf(!string.IsNullOrEmpty(SearchTempText), (a, b) => a.TemplateName.Contains(SearchTempText))
               .ToList((a, b) => new TemplateDto {
                   Id = a.Id,
                   TemplateName = a.TemplateName,
                   TemplatePath = a.TemplatePath,
                   ProductID = a.ProductID,
                   ProductName = b.ProductName,
               });
            Templates.Clear();
            Templates.AddRange(list);
            if (list.Count > 0) {
                SelectTemplateEntity = list.First();
            }
        }

        private void LoadParamsData() {
            if (SelectTemplateEntity != null)
            {
                var list = _mainDbOperate.GetFreeSql().Select<ParamsEntity, TemplateEntity, ViewTableEntity>()
               .LeftJoin((a, b, c) => a.TemplateID == b.Id)
               .LeftJoin((a, b, c) => a.ViewTableID == c.Id)
               .WhereIf(!string.IsNullOrEmpty(SearchParamsText), (a, b, c) => a.ParamsName.Contains(SearchParamsText))
               .Where((a, b, c) => a.TemplateID == SelectTemplateEntity.Id)
               .ToList((a, b, c) => new ParamsDto {
                   Id = a.Id,
                   ParamsName = a.ParamsName,
                   IsTempParams = a.IsTempParams,
                   IsTempParamsLabel = a.IsTempParams ? "是" : "否",
                   IsQrCodeField = a.IsQrCodeField,
                   IsQrCodeFieldLabel = a.IsQrCodeField ? "是" : "否",
                   ParamsKey = a.ParamsKey,
                   ViewTableID = a.ViewTableID,
                   ParamsType = a.ParamsType,
                   IsAccumulatedByDay = a.IsAccumulatedByDay,
                   ValueType = a.ValueType,
                   Length = a.Length,
                   Value = a.Value,
                   Sort = a.Sort,
                   TemplateID = a.TemplateID,
                   IsAccumulatedByDayLabel = a.IsAccumulatedByDay.Value ? "是" : "否",
                   ViewTableName = c.ViewTableName
               }).OrderBy(o => o.Sort);
                Paramss.Clear();
                Paramss.AddRange(list);
            }
        }

        #region 模板参数编辑部分

        private ParamsEntity _paramsEntity;

        public ParamsEntity ParamsEntity {
            get { return _paramsEntity; }
            set { _paramsEntity = value; base.RaisePropertyChanged(); }
        }

        private Visibility _hideViewTable = Visibility.Collapsed;

        public Visibility HideViewTable {
            get { return _hideViewTable; }
            set { _hideViewTable = value; base.RaisePropertyChanged(); }
        }

        private Visibility _hideIsAccumulatedByDay = Visibility.Collapsed;

        public Visibility HideIsAccumulatedByDay {
            get { return _hideIsAccumulatedByDay; }
            set { _hideIsAccumulatedByDay = value; base.RaisePropertyChanged(); }
        }
        

        private ObservableCollection<ComboxItemDto> _paramTypes = new ObservableCollection<ComboxItemDto>();

        public ObservableCollection<ComboxItemDto> ParamTypes {
            get { return _paramTypes; }
            set { _paramTypes = value; base.RaisePropertyChanged(); }
        }


        private ObservableCollection<ComboxItemDto> _valueTypes = new ObservableCollection<ComboxItemDto>();

        public ObservableCollection<ComboxItemDto> ValueTypes {
            get { return _valueTypes; }
            set { _valueTypes = value; base.RaisePropertyChanged(); }
        }

        private ObservableCollection<ViewTableEntity> _viewTables = new ObservableCollection<ViewTableEntity>();

        public ObservableCollection<ViewTableEntity> ViewTables {
            get { return _viewTables; }
            set { _viewTables = value; base.RaisePropertyChanged(); }
        }


        public DelegateCommand<eParamType?> ParamTypeSelectionChangedCommand => new DelegateCommand<eParamType?>((rhs) => {
            var tempValueTemp = ParamsEntity?.ValueType;
            if (ParamsEntity != null)
            {
                ParamsEntity.ValueType = default;
                ParamsEntity.ViewTableID = 0;
            }
            if (rhs == eParamType.Dynamic)
            {
                var vlist = EnumExtensions.ConvertToComboxItems<eValueType>().Where(o => (eValueType)o.Content != eValueType.String);
                ValueTypes.Clear();
                ValueTypes.AddRange(vlist);
                HideViewTable = Visibility.Visible;
            }
            else
            {
                var vlist = EnumExtensions.ConvertToComboxItems<eValueType>().Where(o => (eValueType)o.Content == eValueType.String);
                ValueTypes.Clear();
                ValueTypes.AddRange(vlist);
                HideViewTable = Visibility.Collapsed;
                if (tempValueTemp != null)
                {
                    ParamsEntity.ValueType = tempValueTemp;
                }
            }
        });

        public DelegateCommand<eValueType?> ValueTypeSelectionChangedCommand => new DelegateCommand<eValueType?>((rhs) => {
            if (rhs == eValueType.Day) {
                HideIsAccumulatedByDay = Visibility.Visible;
            } else {
                HideIsAccumulatedByDay = Visibility.Collapsed;
            }
        });

        public DelegateCommand SaveParamsCommand => new DelegateCommand(() => {

            if (string.IsNullOrEmpty(ParamsEntity.ParamsName)) {
                _message.Warning("参数名称不能为空！");
                return;
            }

            if (string.IsNullOrEmpty(ParamsEntity.ParamsKey)) {
                _message.Warning("参数Key不能为空！");
                return;
            }

            if (!ParamsEntity.ParamsType.HasValue) {
                _message.Warning("请选择参数类型！");
                return;
            }

            if (ParamsEntity.ParamsType.Value ==  eParamType.Dynamic 
                && ParamsEntity.ValueType == eValueType.Year
                && ParamsEntity.ValueType == eValueType.Moths
                && ParamsEntity.ValueType == eValueType.Day
                && ParamsEntity.ViewTableID == 0) {
                _message.Warning("请选择一项对照表！");
                return;
            }

            if (!ParamsEntity.ValueType.HasValue) {
                _message.Warning("请选择参数值类型！");
                return;
            }

            if (ParamsEntity.ValueType.Value == eValueType.Day && !ParamsEntity.IsAccumulatedByDay.HasValue ) {
                _message.Warning("请选择是否按天累计！");
                return;
            }

            if (ParamsEntity.ParamsType.Value == eParamType.Fixed) {
                if (string.IsNullOrEmpty(ParamsEntity.Value)) {
                    _message.Warning("参数值不能为空！");
                    return;
                }
            }
            if (ParamsEntity.TemplateID == 0) {
                ParamsEntity.TemplateID = SelectTemplateEntity.Id;
            }
            var res = _mainDbOperate.GetFreeSql().InsertOrUpdate<ParamsEntity>().SetSource(ParamsEntity).ExecuteAffrows();
            if (res > 0) {
                _message.Success("保存成功！");
                IsOpen = false;
                LoadParamsData();
            }

        });

        #endregion

    }
}
